﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;

namespace WindowsPhone.ScreenshotPowerTools
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            Screenshots = new ObservableCollection<string>();
            Screenshots.CollectionChanged += Screenshots_CollectionChanged;
            ChassisPosition = 1;
            SaveCommand = new RelayCommand(Save, CanSave);
        }

        public ObservableCollection<string> Screenshots { get; private set; }

        public int ChassisPosition { get; set; }

        private void Screenshots_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            SaveCommand.RaiseCanExecuteChanged();
        }

        public RelayCommand SaveCommand { get; private set; }

        private void Save()
        {
            int chassisIndex = ChassisPosition - 1;

            string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft XDE\1.0");
            var skinDocument = XDocument.Load(Path.Combine(folderPath, @"WM7_Skin.xml"));
            var view = skinDocument.Descendants("view");
            int displayPosX = int.Parse(view.Attributes("displayPosX").Single().Value);
            int displayPosY = int.Parse(view.Attributes("displayPosY").Single().Value);
            string normalImage = view.Attributes("normalImage").Single().Value;
            var chassisBitmap = new BitmapImage(new Uri(Path.Combine(folderPath, normalImage))) { CreateOptions = BitmapCreateOptions.None };
            int chassisWidth = chassisBitmap.PixelWidth;
            int chassisHeight = chassisBitmap.PixelHeight;

            int x = chassisIndex == 0 ? displayPosX : 0;
            var rect = new Rect { X = x, Y = displayPosY, Height = Constants.ScreenHeight };
            int count = Screenshots.Count;

            int totalWidth = 0;

            var dv = new DrawingVisual();
            using (var dc = dv.RenderOpen())
            {
                for (int i = 0; i < count; i++)
                {
                    var bi = new BitmapImage(new Uri(Screenshots[i])) { CreateOptions = BitmapCreateOptions.None };
                    BitmapSource bitmap = bi;

                    if (i > 0)
                    {
                        int width = Constants.PanoramaItemWidth;
                        if (i == count - 1 && i != chassisIndex)
                        {
                            width -= 24;
                        }
                        bitmap = new CroppedBitmap(bi, new Int32Rect(48, 0, width, Constants.ScreenHeight));
                    }

                    rect.Width = bitmap.PixelWidth;
                    dc.DrawImage(bitmap, rect);
                    rect.X += rect.Width;
                }

                totalWidth = (int)rect.X;
                if (chassisIndex == count - 1)
                {
                    totalWidth += (chassisWidth - displayPosX) - Constants.ScreenWidth;
                }

                int chassisOffsetX = x + Constants.PanoramaItemWidth * chassisIndex - displayPosX;
                dc.PushClip(new CombinedGeometry(
                    GeometryCombineMode.Exclude,
                    new RectangleGeometry(new Rect(0, 0, totalWidth, chassisHeight)),
                    new RectangleGeometry(new Rect(chassisOffsetX + displayPosX, displayPosY, Constants.ScreenWidth, Constants.ScreenHeight))));
                dc.DrawImage(
                    chassisBitmap,
                    new Rect(chassisOffsetX, 0, chassisWidth, chassisHeight));
                dc.Pop();
            }

            var rtb = new RenderTargetBitmap(totalWidth, chassisHeight, 96, 96, PixelFormats.Pbgra32);
            rtb.Render(dv);

            var encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(rtb));

            var saveDialog = new SaveFileDialog()
            {
                Filter = Properties.Resources.PngFilter,
            };
            if (saveDialog.ShowDialog() == true)
            {
                using (var file = File.Create(saveDialog.FileName))
                {
                    encoder.Save(file);
                }

                Process.Start("explorer.exe", saveDialog.FileName);
            }
        }

        private bool CanSave()
        {
            return Screenshots.Count > 0;
        }
    }
}
